﻿using System.Text.RegularExpressions;
using DimensionsHelper.Common.Utils;
using DimensionsHelper.LanguageService.Syntax;

namespace DimensionsHelper.LanguageService;

public partial class Parser
{
    private static readonly SyntaxKinds[] IdentifierOrStringKinds =
        [SyntaxKinds.Identifier, SyntaxKinds.String];

    /// <summary>
    ///     在当前节点<see cref="ParserState.Current" />的起始位置报告诊断信息。
    /// </summary>
    /// <param name="descriptor">诊断信息</param>
    /// <param name="msgArgs">模板替换文本</param>
    private EmptyExpression CreateEmptyExpression(DiagnosticDescriptor? descriptor, params object?[] msgArgs)
    {
        SourceNode reportNode = GetCurrentReportNode();

        if (descriptor != null)
        {
            RaiseAt(descriptor, reportNode.End, msgArgs);
        }

        return FinishNode(NodeFactory.CreateEmptyExpression(reportNode.End), GetEndPoint(reportNode));
    }


    /// <summary>
    ///     将当前节点<see cref="ParserState.Current" />解析为<see cref="Identifier" />，
    ///     此方法会检查当前的上下文类型。
    /// </summary>
    private Identifier ParseIdentifierName(bool allowKeyword = false)
    {
        SourceNode node = GetCurrentNode();
        // keyword
        if (node.IsKeywordToken())
        {
            Identifier kwId = NodeFactory.CreateIdentifier(node);

            // 检查当前上下文，如果在当前的上下文类型中不是关键字，可以直接转换为标识符
            if (!SyntaxFacts.IsKeyword(node.Kind, _state.KeywordContexts) || allowKeyword)
            {
                return FinishNode(kwId, node);
            }

            kwId.SetFlags(SyntaxNodeFlags.InvalidIdentifier);
            Raise(DiagnosticDescriptors.InvalidIdentifiername, node.Span, node.Text);

            return FinishNode(kwId, node);
        }

        // id
        if (node.IsIdentifier)
        {
            return FinishNode(NodeFactory.CreateIdentifier(node), node);
        }

        // missing
        Raise(DiagnosticDescriptors.UnexpectedToken, node.Start, node.Start + 1,
            IdentifierName);
        Identifier missing = NodeFactory.CreateIdentifier();
        missing.Update(GetReportNode(node).Start, GetReportNode(node).Width);
        return missing;
    }


    /// <summary>
    ///     在某些情况下，命名的标识符可以写成字符串，在解析时，
    ///     需要进行转换。
    /// </summary>
    private Identifier ParseIdentifierLike()
    {
        SourceNode current = GetCurrentNode();

        if (current.IsNode(SyntaxKinds.Identifier) ||
            current.IsKeywordToken())
        {
            return ParseIdentifierName(true);
        }

        if (current.IsNode(SyntaxKinds.String))
        {
            StringLiteral stringLiteral = ParseString();

            if (StringHelper.IsValidIdentifier(stringLiteral.Text))
            {
                return NodeConverter.ToIdentifier(stringLiteral, null);
            }

            Raise(DiagnosticDescriptors.InvalidIdentifiername,
                stringLiteral, stringLiteral.Text);
        }
        else
        {
            Raise(DiagnosticDescriptors.UnexpectedToken,
                current, IdentifierName);
        }

        return Identifier.Default;
    }


    [GeneratedRegex(@"[^\r\n_\\](?=\r|\n)")]
    private static partial Regex GetStringLineFeedRegex();


    private void CheckStringLineFeed()
    {
        SourceNode currentNode = GetCurrentNode();
        string text = currentNode.Text;
        Regex regex = GetStringLineFeedRegex();
        MatchCollection matches = regex.Matches(text);

        foreach (Match match in matches)
        {
            if (!match.Success)
            {
                continue;
            }

            int pos = currentNode.Start + match.Index + 1;
            Raise(DiagnosticDescriptors.LostStringLiteralLineFeed, pos, 1);
        }
    }


    /// <summary>
    ///     将当前的 <see cref="SourceNode" /> 解析为 <see cref="StringLiteral" />。
    ///     不调用 <see cref="Next" /> 方法。
    /// </summary>
    private StringLiteral ParseString()
    {
        if (!_state.GetKeywordContexts(KeywordContexts.Metadata) &&
            !GetCurrentNode().GetFlags(SyntaxNodeFlags.MultilineString))
        {
            CheckStringLineFeed();
        }

        StringLiteral literal = NodeFactory.CreateStringLiteral(GetCurrentNode());
        return FinishNode(literal);
    }


    /// <summary>
    ///     解析当前的字符串或标识符，并转换为字符串返回。
    /// </summary>
    private StringLiteral ParseStringLike()
    {
        SourceNode current = GetCurrentNode();
        if (current.IsNode(SyntaxKinds.String))
        {
            return ParseString();
        }

        if (current.IsNode(SyntaxKinds.Identifier))
        {
            return FinishNode(NodeFactory.CreateStringLiteral(null, false, current.Text),
                current);
        }

        Raise(DiagnosticDescriptors.UnexpectedToken, "标识符或字符串");
        return StringLiteral.Default;
    }


    private StringLiteral ParseContinuousTokenAsString(params SyntaxKinds[] stopKinds)
    {
        SourceNode token = GetCurrentNode();
        // 字符串节点
        if (token.IsString)
        {
            return ParseString();
        }

        List<SourceNode> tokenList = [token];

        while (!Eof() && IsNextContinuous())
        {
            tokenList.Add(GetCurrentNode());
        }

        return NodeConverter.CombineAsString(tokenList);

        bool IsNextContinuous()
        {
            return TryParse<ITextNode>(ParseNextStop, out _);
        }

        SourceNode? ParseNextStop()
        {
            SourceNode current = GetCurrentNode();
            SourceNode next = Next();

            if (next.Start == current.EndLine && !next.IsOneOfNode(stopKinds))
            {
                return next;
            }

            return null;
        }
    }

    /// <summary>
    ///     将当前的 <see cref="SourceNode" /> 解析为 <see cref="IntegerLiteral" />，
    ///     不调用 <see cref="Next" /> 方法。
    /// </summary>
    private IntegerLiteral ParseInteger()
    {
        IntegerLiteral integer = NodeFactory.CreateIntegerLiteral(GetCurrentNode());
        return FinishNode(integer);
    }


    /// <summary>
    ///     将当前的 <see cref="SourceNode" /> 解析为 <see cref="DoubleLiteral" />，
    ///     不调用 <see cref="Next" /> 方法。
    /// </summary>
    private DoubleLiteral ParseDouble()
    {
        DoubleLiteral db = NodeFactory.CreateDoubleLiteral(GetCurrentNode());
        return FinishNode(db);
    }


    /// <summary>
    ///     将当前的 <see cref="SourceNode" /> 解析为 <see cref="BooleanLiteral" />，
    ///     不调用 <see cref="Next" /> 方法。
    /// </summary>
    private BooleanLiteral ParseBoolean()
    {
        BooleanLiteral bln = NodeFactory.CreateBooleanLiteral(GetCurrentNode());
        return FinishNode(bln);
    }


    /// <summary>
    ///     将当前的 <see cref="SourceNode" /> 解析为 <see cref="NullLiteral" />，
    ///     不调用 <see cref="Next" /> 方法。
    /// </summary>
    private NullLiteral ParseNull()
    {
        NullLiteral nullLiteral = NodeFactory.CreateNullLiteral(GetCurrentNode());
        return FinishNode(nullLiteral);
    }


    /// <summary>
    ///     单个分类表达式，
    /// </summary>
    private CategoryLiteral? ParseCategory()
    {
        // ^
        SyntaxToken? caretSourceToken = OptionalCurrentToken(SyntaxKinds.CaretToken);
        // Integer | [LeftBound][..][RightBound]
        IntegerLiteral? intNode = null;
        Identifier? leftBound = null;
        SyntaxToken? dotDotToken = null;
        Identifier? rightBound = null;
        // 当前字符
        SourceNode node = GetCurrentNode();
        // 数字
        if (node.IsNumber)
        {
            // 不允许小数
            if (node.IsNode(SyntaxKinds.Double))
            {
                Raise(DiagnosticDescriptors.UnexpectedToken, "整数");
            }
            else
            {
                intNode = ParseInteger();
            }
        }
        // 标识符
        else if (node.IsIdentifier)
        {
            leftBound = ParseIdentifierName(true);
            // ..
            dotDotToken = Optional(SyntaxKinds.DotDotToken);
            // rightBound
            if (dotDotToken != null && TryParse(SyntaxKinds.Identifier))
            {
                rightBound = ParseIdentifierName(true);
            }
        }
        else
        {
            Raise(DiagnosticDescriptors.UnexpectedAmpersand, "标识符 或 整数");
        }

        if (intNode != null)
        {
            return FinishNode(NodeFactory.CreateCategoryLiteral(null, intNode));
        }

        if (!Identifier.IsDefaultOrEmpty(leftBound) ||
            dotDotToken != null ||
            !Identifier.IsDefaultOrEmpty(rightBound))
        {
            CategoryLiteral category =
                NodeFactory.CreateCategoryLiteral(null, caretSourceToken, leftBound, dotDotToken, rightBound);
            return FinishNode(category);
        }

        return null;
    }


    /// <summary>
    ///     当前Token是<see cref="SyntaxKinds.LeftCurlyToken" />并且不在元数据代码中时，
    ///     视为分类值表达式。最后会停在 '}' 处或文本末尾。
    /// </summary>
    private CategoricalLiteral ParseCategorical()
    {
        SyntaxPoint start = GetCurrentStartPoint();
        // {
        SyntaxToken leftCurlyToken = GetToken();
        List<CategoryLiteral> categories = new();
        // -> } | EOF
        while (!CurrentIsOneOf(SyntaxKinds.RightCurlyToken, SyntaxKinds.Eof))
        {
            // 不允许换行
            if (IsLineEnd())
            {
                RaiseAt(DiagnosticDescriptors.UnexpectedToken, GetCurrentSpan().End, "}");
                break;
            }

            SourceNode current = Next();

            // .. | ^ | 整数 | 标识符
            if (SyntaxFacts.IsKeyword(current.Kind) ||
                current.IsOneOfNode(SyntaxKinds.CaretToken, SyntaxKinds.Identifier, SyntaxKinds.DotDotToken,
                    SyntaxKinds.Integer))
            {
                CategoryLiteral? category = ParseCategory();
                if (category != null)
                {
                    categories.Add(category);
                }

                // 节点后没有换行时，期望 , | }
                if (!IsLineEnd())
                {
                    Expect([SyntaxKinds.CommaToken, SyntaxKinds.RightCurlyToken]);
                }
            }
            // , -> 空分类值
            else if (current.IsNode(SyntaxKinds.CommaToken))
            {
                CategoryLiteral emptyCategory = NodeFactory.CreateCategoryLiteral(null, null,
                    null, null, null);
                SyntaxPoint point = GetCurrentStartPoint();
                categories.Add(FinishNode(emptyCategory, point, 1));
            }
            else
            {
                Raise(DiagnosticDescriptors.InvlidCategoryValue, current);
            }
        }

        // }
        SyntaxToken rightCurlyToken = ExpectCurrent(SyntaxKinds.RightCurlyToken) ?? SyntaxToken.Default;
        CategoricalLiteral literal = NodeFactory.CreateCategoricalLiteral(null, leftCurlyToken,
            rightCurlyToken, categories);
        return FinishNode(literal, start);
    }


    /// <summary>
    ///     从当前节点<see cref="ParserState.Current" />开始读取代码表达式，
    ///     不调用 <see cref="Next" /> 方法
    /// </summary>
    private Expression ParseExpressionFromCurrent(bool parseBinaryOperator = true,
        bool allowAssignment = true)
    {
        SourceNode node = GetCurrentNode();
        SyntaxPoint start = GetCurrentStartPoint();

        // Set
        if (node.IsNode(SyntaxKinds.SetKeywordToken))
        {
            SyntaxToken setKeywordToken = GetToken();
            Expression assignment = ParseExpression();

            // 赋值表达式失败，直接返回空表达式
            if (Expression.IsEmptyExpression(assignment))
            {
                return assignment;
            }

            // 不是赋值表达式，报告错误并返回空表达式
            if (!assignment.Is<AssignmentExpression>(SyntaxKinds.AssignmentExpression,
                    out AssignmentExpression? assignExpr))
            {
                Raise(DiagnosticDescriptors.UnexpectedToken, assignment.Span, "赋值表达式");
                return CreateEmptyExpression(null);
            }

            assignExpr.Set(setKeywordToken);
            return FinishNode(assignExpr, start);
        }

        Expression expression;

        // (
        if (node.IsNode(SyntaxKinds.LeftParenthesisToken))
        {
            SyntaxToken leftParenthesisToken = GetToken();
            // 不允许换行
            if (IsLineEnd())
            {
                return CreateEmptyExpression(DiagnosticDescriptors.UnexpectedToken, ExpressionName);
            }

            Expression innerExpr = ParseExpression(allowAssignment: false);
            SyntaxToken rightParenthesisToken = Expect(SyntaxKinds.RightParenthesisToken);
            innerExpr.Update(leftParenthesisToken, rightParenthesisToken);
            expression = FinishNode(innerExpr, start);
        }
        else
        {
            expression = ParseExpressionOperand();
        }

        if (parseBinaryOperator)
        {
            SourceNode? operatorNode = TryParse(() =>
            {
                SourceNode next = Next();
                return next.IsScriptBinaryOperator ? next : null;
            });

            if (operatorNode != null)
            {
                // 区分二元表达式和赋值表达式
                if (allowAssignment &&
                    operatorNode.IsNode(SyntaxKinds.EqualToken) &&
                    !expression.IsOneOfNode(SyntaxKinds.BinaryExpression, SyntaxKinds.UnaryExpression))
                {
                    return ParseAssignmentExpression(expression);
                }

                expression = ParseBinaryExpression(expression);
            }
        }

        // 不修改空表达式的内容
        return Expression.IsEmptyExpression(expression)
            ? expression
            : FinishNode(expression, start);
    }


    /// <summary>
    ///     解析语法表达式，此方法会先调用<see cref="Next" />方法读取下一个节点，
    ///     再读取后续的表达式内容。
    /// </summary>
    /// <param name="parseBinaryOperator">是否尝试向后解析二元表达式</param>
    /// <param name="allowAssignment">是否将第一个等号解析为赋值符号</param>
    /// <remarks>
    ///     如果当前节点后换行，报告错误并返回空表达式
    /// </remarks>
    private Expression ParseExpression(bool parseBinaryOperator = true, bool allowAssignment = true)
    {
        if (IsLineEnd())
        {
            return CreateEmptyExpression(DiagnosticDescriptors.UnexpectedToken, ExpressionName);
        }

        Next();
        return ParseExpressionFromCurrent(parseBinaryOperator, allowAssignment);
    }


    private UnaryExpression ParseUnaryExpression()
    {
        SyntaxToken operatorToken = GetToken();
        Expression expression = ParseExpression(false);
        UnaryExpression unary = NodeFactory.CreateUnaryExpression(operatorToken, expression);
        return FinishNode(unary, GetStartPoint(operatorToken));
    }


    /// <summary>
    ///     处理二元表达式，优先级更高或者两侧带有括号的表达式位于树的下层。
    /// </summary>
    /// <param name="leftOperand">左侧表达式</param>
    /// <returns>二元表达式</returns>
    /// <remarks>
    ///     对于表达式 A * B + C / (D - E)
    ///     结果应当如下：
    ///     <code>
    ///        +
    ///     /     \
    ///    *      /
    ///   / \   /   \
    ///  A   B C     -
    ///             / \
    ///            D   E
    /// </code>
    /// </remarks>
    private BinaryExpression ParseBinaryExpression(Expression leftOperand)
    {
        SyntaxToken operatorToken = GetToken();
        Expression rightOperand = ParseExpression(true, false);
        // 读取表达式时，从左向右依次读取，二元操作符表达式应该依次读取：
        // Expr1 And Expr2 Or Expr3
        //   |        |        |
        //   +--------+        |
        //       |             |
        //    Binary1          |
        //       |             |
        //       +-------------+
        //             |
        //          Binary2
        // 而实际上，在递归调用ParseExpression方法时，各个二元表达式是从右向左组织的。
        // 此时，需要检查左右侧表达式的类型：
        // 如果有一个是二元表达式，需要比较操作符的优先级，优先级更高的操作符放在语法树的下层
        if (rightOperand.LeftParenthesisToken == null && // 如果右侧表达式带有括号，则不需要检查优先级
            rightOperand.Is<BinaryExpression>(out BinaryExpression? rightBinary) &&
            SyntaxFacts.TryConvertSyntaxKindsToOperatorPriority(rightBinary.OperatorToken.Kind,
                OperatorContexts.Script, out int rightPriority) &&
            SyntaxFacts.TryConvertSyntaxKindsToOperatorPriority(operatorToken.Kind,
                OperatorContexts.Script, out int leftPriority) &&
            leftPriority > rightPriority)
        {
            // 右侧表达式放在左侧表达式的右侧，并返回左侧表达式leftOperand
            //
            //  A [OP] B * C
            //     ^
            //  A [OP] -> ParseExpression -> *
            //                              / \
            //                             B   C
            //  比较 OP 和 * 的优先级，此时:
            //  1. 如果 OP 的优先级大于 * 的优先级，结果应当如下：
            //     [OP]              *
            //     /  \     ->      / \
            //    A    B          [OP] C
            //                    / \
            //                   A   B
            //  2. 如果 OP 的优先级小于等于 * 的优先级，结果应当如下：
            //      [OP]
            //      / \
            //     A   *
            //        / \
            //       B   C
            Expression rightLeft = rightBinary.LeftOperand;
            BinaryExpression leftBinary = NodeFactory.CreateBinaryExpression(operatorToken,
                leftOperand, rightLeft);
            FinishNode(leftBinary, GetStartPoint(leftOperand), GetEndPoint(rightLeft));
            rightBinary.Update(leftBinary, rightBinary.RightOperand);
            return FinishNode(rightBinary, GetStartPoint(leftOperand), GetEndPoint(rightOperand));
        }

        BinaryExpression binary = NodeFactory.CreateBinaryExpression(operatorToken, leftOperand, rightOperand);
        return FinishNode(binary, GetStartPoint(leftOperand));
    }


    /// <summary>
    ///     赋值表达式，可能带有 Set 关键字。
    ///     读取节点时也相对简单，不需要右侧表达式是二元操作符的情况。
    /// </summary>
    /// <param name="leftOperand">左值表达式</param>
    private AssignmentExpression ParseAssignmentExpression(Expression leftOperand)
    {
        SyntaxToken operatorToken = GetToken();
        Expression rightOperand = ParseExpression(true, false);
        AssignmentExpression assignment = NodeFactory.CreateAssignmentExpression(null, operatorToken, leftOperand,
            rightOperand);
        return FinishNode(assignment, GetStartPoint(leftOperand));
    }


    /// <summary>
    ///     解析成员表达式，其中，表达式对象允许忽略
    ///     语法格式 -> [Object].Member
    /// </summary>
    private MemberExpression ParseMemberExpression(Expression objectExpression, SyntaxPoint point)
    {
        while (true)
        {
            SyntaxToken dotToken = GetToken();
            Identifier memberName = ExpectIdentifier(true);
            MemberExpression expr = NodeFactory.CreateMemberExpression(null, objectExpression,
                dotToken, memberName);

            FinishNode(expr, point);

            if (!TryParse(SyntaxKinds.DotToken))
            {
                return expr;
            }

            objectExpression = expr;
        }
    }


    private ArgumentList ParseArgumentList()
    {
        SyntaxToken startToken = GetToken();
        SyntaxKinds endKind = startToken.IsNode(SyntaxKinds.LeftParenthesisToken)
            ? SyntaxKinds.RightParenthesisToken
            : SyntaxKinds.RightBracketToken;

        List<Expression> args = [];

        if (!TryParse(endKind) && !IsLineEnd())
        {
            while (true)
            {
                SourceNode node = Next();
                // 空参数
                if (node.IsNode(SyntaxKinds.CommaToken))
                {
                    args.Add(CreateEmptyExpression(null));
                }
                // ..[ In CategoriesName]
                else if (node.IsNode(SyntaxKinds.DotDotToken) &&
                         endKind == SyntaxKinds.RightBracketToken)
                {
                    args.Add(ParseObjectCollectionIteration());
                }
                else
                {
                    args.Add(ParseExpressionFromCurrent(true, false));
                }

                // 不是结束括号 或 EOF，期望 逗号 ','
                if (!IsLineEnd() && !TryParse(endKind))
                {
                    // 如果是空参数，当前的节点就是逗号，此处需要跳过
                    if (!node.IsNode(SyntaxKinds.CommaToken))
                    {
                        Expect(SyntaxKinds.CommaToken);
                    }
                }
                else
                {
                    break;
                }
            }
        }

        SyntaxToken? endToken = ExpectCurrent(endKind);
        ArgumentList list = NodeFactory.CreateArgumentList(null, startToken, endToken, args);
        return FinishNode(list, GetStartPoint(startToken));
    }


    /// <summary>
    ///     索引表达式，语法 objectExpression[arg[, arg1]...]，最后会停在 ']' 处，
    ///     需要当前节点是'['
    /// </summary>
    /// <param name="obj">调用对象表达式</param>
    private IndexExpression ParseIndexExpression(Expression obj)
    {
        ArgumentList argList = ParseArgumentList();
        IndexExpression indexExpr = NodeFactory.CreateIndexExpression(null, obj, argList);
        return FinishNode(indexExpr, GetStartPoint(obj));
    }


    /// <summary>
    ///     函数调用表达式，语法 callee([arg1[, arg2]...])，最后会停在 ')' 处，
    ///     需要当前节点是'('
    /// </summary>
    /// <param name="callee">函数调用表达式，一般是<see cref="Identifier" />或<see cref="MemberExpression" /></param>
    private CallExpression ParseCallExpression(Expression callee)
    {
        ArgumentList argList = ParseArgumentList();
        CallExpression callExpr = NodeFactory.CreateCallExpression(null, callee, argList);
        return FinishNode(callExpr, GetStartPoint(callee));
    }


    /// <summary>
    ///     对象集合索引的迭代表达式，objectExpression[..[ In CategoriesName]]
    /// </summary>
    private ObjectCollectionIteration ParseObjectCollectionIteration()
    {
        SyntaxToken dotDotToken = GetToken();
        SyntaxToken? inKeywordToken = Optional(SyntaxKinds.InKeywordToken);
        Identifier? categoriesName = null;
        if (inKeywordToken != null)
        {
            categoriesName = ExpectIdentifier(true);
        }

        ObjectCollectionIteration iteration = NodeFactory.CreateObjectCollectionIteration(null, dotDotToken);
        if (inKeywordToken != null && categoriesName != null)
        {
            iteration.Update(inKeywordToken, categoriesName);
        }

        return FinishNode(iteration, GetStartPoint(dotDotToken));
    }


    private Expression ParseIdentifierOrHigher()
    {
        Expression expr = ParseIdentifierName();

        while (!IsLineEnd())
        {
            if (TryParse(
                    [SyntaxKinds.DotToken, SyntaxKinds.LeftParenthesisToken, SyntaxKinds.LeftBracketToken],
                    out SourceNode? node))
            {
                if (node.IsNode(SyntaxKinds.DotToken))
                {
                    expr = ParseMemberExpression(expr, GetStartPoint(expr));
                }
                else if (node.IsNode(SyntaxKinds.LeftBracketToken))
                {
                    expr = ParseIndexExpression(expr);
                }
                else
                {
                    expr = ParseCallExpression(expr);
                }
            }
            else
            {
                break;
            }
        }

        return expr;
    }


    private Expression ParseExpressionOperand()
    {
        SourceNode node = GetCurrentNode();

        // 一元表达式
        if (node.IsScriptUnaryOperator)
        {
            return ParseUnaryExpression();
        }

        // .MemberExpression
        Expression obj = Identifier.Default;
        Expression? expr = null;
        while (CurrentIs(SyntaxKinds.DotToken))
        {
            expr = ParseMemberExpression(obj,
                Expression.IsEmptyExpression(obj) ? GetStartPoint(node) : GetStartPoint(obj));
            obj = expr;
            // [ | (
            if (TryParse([SyntaxKinds.LeftBracketToken, SyntaxKinds.LeftParenthesisToken], out _))
            {
                // (
                if (CurrentIs(SyntaxKinds.LeftParenthesisToken))
                {
                    expr = ParseCallExpression(obj);
                    obj = expr;
                }
                // [
                else
                {
                    expr = ParseIndexExpression(obj);
                    obj = expr;
                }
            }

            // 后续不是'.'，跳出
            if (!TryParse(SyntaxKinds.DotToken))
            {
                break;
            }
        }

        if (expr != null)
        {
            return expr;
        }

        // 常量
        return node.Kind switch
        {
            // string
            SyntaxKinds.String => ParseString(),
            // integer
            SyntaxKinds.Integer => ParseInteger(),
            // double
            SyntaxKinds.Double => ParseDouble(),
            // boolean
            SyntaxKinds.TrueKeywordToken or SyntaxKinds.FalseKeywordToken =>
                ParseBoolean(),
            // null
            SyntaxKinds.NullKeywordToken => ParseNull(),
            // categorical
            SyntaxKinds.LeftCurlyToken => ParseCategorical(),
            // .
            SyntaxKinds.DotToken => ParseMemberExpression(Identifier.Default, GetStartPoint(node)),
            // identifier
            _ => ParseIdentifierOrHigher()
        };
    }


    private SelectCaseComparison ParseSelectCaseComparision()
    {
        SourceNode node = Next();
        // > | >= | < | <= | = Expression | Expression
        Expression expression;
        SelectCaseComparison comparison;

        if (SyntaxFacts.IsCompareOperatorUnchecked(node.Kind))
        {
            SyntaxToken compareOperator = GetToken();
            expression = ParseExpression(allowAssignment: false);
            comparison = NodeFactory.CreateSelectCaseComparision(null, compareOperator, expression);
        }
        else
        {
            expression = ParseExpressionFromCurrent(allowAssignment: false);
            // To
            SyntaxToken? toKeywordToken = Optional(SyntaxKinds.ToKeywordToken);
            if (toKeywordToken != null)
            {
                Expression rightBound = IsLineEnd() ? EmptyExpression.Default : ParseExpression(allowAssignment: false);
                expression = NodeFactory.CreateRangeExpression(expression, toKeywordToken, rightBound, null);
            }
            comparison = NodeFactory.CreateSelectCaseComparision(null, expression);
        }

        return FinishNode(comparison, GetStartPoint(node));
    }
}